package com.swust.ipmsg.activity;


import java.io.IOException;
import java.lang.reflect.Field;
import java.net.DatagramPacket;
import java.net.InetAddress;
import java.net.MulticastSocket;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Random;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.style.ImageSpan;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ListView;
import android.widget.SimpleAdapter;
import android.widget.TextView;

import com.swust.ipmsg.IPMsgApplication;
import com.swust.ipmsg.R;

public class ChatActivity extends Activity {// 建立Muticast类，继承Activity类
	protected static final String MULTICAST_ADDRESS = "230.6.6.6";// *作为多播组的地址
	// 添加控件
	TextView myTextView = null;
	public EditText myEditText = null;
	private Button myButton = null;
	private Button myButtonConnect = null;
	//private Button myButtonUnConnect = null;
	private Button insertButton = null;
	private Button reset = null;

	int Port = 57111;// 定义端口，用整型数据表（整数）示端口号
	private MulticastSocket Socket = null;// 定义多播类型的套接字
	MyHandler myHandler = null;// 定义Myhandler对象

	HashMap<String, Object> map = new HashMap<String, Object>();

	Message msg = new Message();
	ArrayList<HashMap<String, Object>> listItem = new ArrayList<HashMap<String, Object>>();

	public void onCreate(Bundle savedInstanceState) {// Activity的OnCreate方法
		super.onCreate(savedInstanceState);// 调用父类的OnCreate方法
		IPMsgApplication.getInstance().addActivity(this);
		// 取消标题
		this.requestWindowFeature(Window.FEATURE_NO_TITLE);

		// 进行全屏
		this.getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);

		setContentView(R.layout.activity_chat);// 加载布局xml文件
		// System.out.println("onCreate Run Succeed!");//输出一句话

		// 用 findViewById(R.id.XXX);方法获得控件的ID。
		myTextView = (TextView) findViewById(R.id.myTextView);
		myEditText = (EditText) findViewById(R.id.myEditView);
		myButton = (Button) findViewById(R.id.myButton);
		myButtonConnect = (Button) findViewById(R.id.myButtonConnect);
		//myButtonUnConnect = (Button) findViewById(R.id.myButtonUnConnect);
		myButton.setText(R.string.send);// Button上的字
		myButtonConnect.setText(R.string.Connect);
		//myButtonUnConnect.setText(R.string.UnConnect);
		insertButton = (Button) findViewById(R.id.insert);
		insertButton.setText(R.string.Insert);
		reset = (Button)findViewById(R.id.reset);
		myHandler = new MyHandler();// 实例化myHandler
		Receive recieve = new Receive(Port);// 定义一个Recieve线程对象。

		// 绑定Layout里面的ListView
		ListView list = (ListView) findViewById(R.id.ListView01);

		// 生成动态数组，加入数据

		for (int i = 0; i < 10; i++) {

			map.put("ItemImage", null);// 图像资源的ID
			map.put("ItemTitle", null);
			listItem.add(map);
		}

		// 生成适配器的Item和动态数组对应的元素
		SimpleAdapter listItemAdapter = new SimpleAdapter(this, listItem,// 数据源
				R.layout.list_items,// ListItem的XML实现
				// 动态数组与ImageItem对应的子项
				new String[] { "ItemImage", "ItemTitle", "ItemText" },
				// ImageItem的XML文件里面的一个ImageView,两个TextView ID
				new int[] { R.id.ItemImage, R.id.ItemTitle, R.id.ItemText });
		// 添加并且显示
		list.setAdapter(listItemAdapter);

		new Thread(recieve).start();// 开始新线程的执行
		myButtonConnect.setOnClickListener(new Button.OnClickListener() {
			// 点击myButtonConnect的响应连接事件

			public void onClick(View v) {
				try {
					Socket = new MulticastSocket(Port);// 一个组播Socket，上行提起的接口在本地主机
					Socket.joinGroup(InetAddress.getByName(MULTICAST_ADDRESS));// 加这Socket到多播组。一个Socket必须加入一个组在基准可能收到前。一个Socket可隶属于多种组，而可以加入任何组只有一次
					System.out.println("Connect Succeed!");
				} catch (IOException e) {
					// 捕捉错误
					e.printStackTrace();
				}
			}
		});

		myButton.setOnClickListener(new Button.OnClickListener() {
			// 点击发送事件

			public void onClick(View v) {
				// myTextView.setText(myEditText.getText());
				String str = myEditText.getText().toString();// 得到消息内容
				byte[] b = str.getBytes();// 返回一个新字节数组包含字符的这串编码使用系统默认字符集
				DatagramPacket packet = new DatagramPacket(b, b.length);// 创建一个DatagramPacket对象接收数据
				// 接受的数据包长度为length个字节。 DatagramPacket对象中包括通过DatagramSocket传输的数据。
				try {
					packet.setAddress(InetAddress.getByName(MULTICAST_ADDRESS));// 集设定接口的网络逻辑地址的目标主机
				} catch (UnknownHostException e) {
					e.printStackTrace();
				}

				// 设置目标主机的IP地址。
				packet.setPort(Port);// 设置这个数据包目标主机的端口号。

				try {
					Socket.send(packet);// 发送消息
					// myEditText.setText(null);//发送完后置空
					System.out.println("Send Succeed!");
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		});

		//myButtonUnConnect.setOnClickListener(new Button.OnClickListener() {
			// 取消连接事件
			//public void onClick(View v) {
			//	Socket.close();// 关闭这个低层协议数据套接字所有可能的渠道
				// System.out.println("UnConnect Succeed!");
			//}
		//});

	}

	class MyHandler extends Handler {
		public MyHandler() {
		}

		public MyHandler(Looper L) {
			super(L);
		}

		public void handleMessage(Message msg) {
			Log.d("MyHandler", "handleMessage......");// 调试日志。//Log.d的输出颜色是蓝色的，仅输出debug调试的意思，但他会输出上层的信息，过滤起来可以通过DDMS的Logcat标签来选择
			super.handleMessage(msg);// super在java中代表当前对象的父类对象（与之相应，this代表当前对象），即调用父类中的同名方法
			// 此处跟新ＵＩ
			Bundle bundle = msg.getData();// getData:获得一束随意的基准关联说完这个事件
			String information = bundle.getString("information");// 返回关联文件给定关键,或设置空字符没有测绘类型存在为给定关键或一个空值明确地关联文件关键

			map.put("ItemText", information);

		}
	}

	// 插入随机表情
	public void onClick_RandomFace(View v) {
		// TODO Auto-generated method stub

		// 随机产生1至9的整数
		int randomId = 1 + new Random().nextInt(9);
		System.out.println("Image1!");

		try {
			// 根据随机产生的1至9的整数从R.drawable类中获得相应资源ID（静态变量）的Field对象
			Field field = R.drawable.class.getDeclaredField("p" + randomId);
			System.out.println("Image2!");
			// 获得资源ID的值，也就是静态变量的值
			int resourceId = Integer.parseInt(field.get(null).toString());
			System.out.println("Image3!");
			// 根据资源ID获得资源图像的Bitmap对象
			Bitmap bitmap = BitmapFactory.decodeResource(getResources(),
					resourceId);
			System.out.println("Image4!");
			// 根据Bitmap对象创建ImageSpan对象,添加图片主要用SpannableString和ImageSpan类
			ImageSpan imageSpan = new ImageSpan(bitmap);
			System.out.println("Image5!");
			// 创建一个SpannableString对象，以便插入用ImageSpan对象封装的图像
			SpannableString spannableString = new SpannableString("p");
			// 用ImageSpan对象替换face
			System.out.println("Image6!");
			spannableString.setSpan(imageSpan, 0, 1,
					Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
			System.out.println("Image7!");
			// 将随机获得的图像追加到EditText控件的最后
			myEditText.append(spannableString);
			map.put("ItemImage", spannableString);
			System.out.println("Image8!");
		} catch (Exception e) {
		}

	}

	public class Receive implements Runnable {
		private static final int BUFFER_LENGTH = 1024;
		private static final String MULTICAST_ADDRESS = "230.6.6.6";

		private int Port = 57111;
		private MulticastSocket Socket;

		public Receive(int Port) {
			this.Port = Port;
		}

		public void run() {
			try {
				this.Socket = new MulticastSocket(this.Port);
				Socket.joinGroup(InetAddress.getByName(MULTICAST_ADDRESS));
			} catch (IOException e) {
				e.printStackTrace();
			}

			try {
				this.waitForResponse();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}

		public void closeSocket() {
			this.Socket.close();
		}

		public String waitForResponse() throws IOException {
			// 接收消息事件

			while (true) {
				Bundle bundle = new Bundle();
				Message msg = new Message();
				byte[] b = new byte[BUFFER_LENGTH];
				DatagramPacket packet = new DatagramPacket(b, b.length);

				this.Socket.receive(packet);
				System.out.println("Recieve Succeed!");
				String information = new String(packet.getData());
				// Copies this string removing white space characters from the
				// beginning and end of the string.

				information = information.trim();

				Log.d("Thread......", "mThread......");

				if (packet.getPort() == Port) {
					System.out.println("Return Succeed!");
					msg.arg1 = 1;
					bundle.putString("information", information);
					msg.setData(bundle);// 设置一组随意的数据值
					ChatActivity.this.myHandler.sendMessage(msg);// msg是指发生的消息
				}
			}
		}
	}
}
